package cn.buk.tms.eotms.dao;

import cn.buk.common.util.DateUtil;
import cn.buk.tms.eotms.dao.factory.OperationLogFactory;
import cn.buk.tms.eotms.entity.*;
import cn.buk.tms.eotms.sc.SearchFlightOrderCriteria;
import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

import static cn.buk.tms.common.constant.TmsOrderConstant.*;


@Component
@Transactional
public class VasOrderDaoImpl extends AbstractDao implements VasOrderDao {

  @Override
  public List<VasOrder> searchVasOrders(final int ownerId, final int customerId, SearchFlightOrderCriteria sc, final boolean isInsurance) {
    List<VasOrder> results = null;

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<VasOrder> cq = cb.createQuery(VasOrder.class);
    Root<VasOrder> root = cq.from(VasOrder.class);
    root.alias("o");

    var predicates0 = getPredicates_searchVasOrders(ownerId, customerId, sc, isInsurance, cb, root);


    //计算根据条件查询得出的数据总数
    CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
    Root<VasOrder> countRoot = countQuery.from(VasOrder.class);
    countRoot.alias("o");

    var predicates1 = getPredicates_searchVasOrders(ownerId, customerId, sc, isInsurance, cb, countRoot);

    // count items
    countQuery.select(cb.count(countRoot)).where(predicates1.toArray(new Predicate[predicates1.size()]));
    Long count = em.createQuery(countQuery).getSingleResult();

    //查询
    cq.select(root).where(predicates0.toArray(new Predicate[predicates0.size()]));

    List<Order> orderByes = new ArrayList<>();
    orderByes.add(cb.desc(root.get("id")));

    cq.orderBy(orderByes);

    int maxResults = count.intValue();
    if (maxResults > 0) {
      sc.getPage().setRowCount(maxResults);

      results = em.createQuery(cq)
          .setFirstResult(sc.getPage().getFirstPosition())
          .setMaxResults(sc.getPage().getPageSize())
          .getResultList();

      for (VasOrder order : results) {
        order.getPassengers().size();
        order.getFlights().size();
      }
    }

    if (results == null) {
      results = new ArrayList<>();
    }

    return results;
  }

  private List<Predicate> getPredicates_searchVasOrders(int ownerId, int customerId, SearchFlightOrderCriteria sc, boolean isInsurance, CriteriaBuilder cb, Root<VasOrder> root) {
    List<Predicate> predicates = new ArrayList<>();

    Predicate predicate = cb.conjunction();
    predicates.add(predicate);

    predicate = cb.equal(root.get(VasOrder_.enterpriseId), ownerId);
    predicates.add(predicate);

    predicate = cb.equal(root.get(VasOrder_.customerId), customerId);
    predicates.add(predicate);

    if (isInsurance) {
      predicate = cb.equal(root.get(VasOrder_.productType), TieInProduct.INSURANCE);
      predicates.add(predicate);
    } else {
      predicate = cb.notEqual(root.get(VasOrder_.productType), TieInProduct.INSURANCE);
      predicates.add(predicate);
    }

    if (sc.getStatus() > -1) {
      predicate = cb.equal(root.get(VasOrder_.status), sc.getStatus());
      predicates.add(predicate);
    }

    if (sc.getOrderNo().length() > 0) {
      predicate = cb.equal(root.get(VasOrder_.orderNo), sc.getOrderNo());
      predicates.add(predicate);
    }

    if (sc.getStatus() == -1 && sc.getOrderNo().length() == 0) {
      predicate = cb.notEqual(root.get(VasOrder_.status), ORDER_STATUS_CANCELED);
      predicates.add(predicate);
    }

    if (sc.getBeginDate() != null) {
      predicate = cb.greaterThanOrEqualTo(root.get(VasOrder_.createDate), sc.getBeginDate());
      predicates.add(predicate);
    }

    if (sc.getEndDate() != null) {
      predicate = cb.lessThanOrEqualTo(root.get(VasOrder_.createDate), sc.getEndDate());
      predicates.add(predicate);
    }


    if (sc.getProductCode() != null && sc.getProductCode().trim().length() > 0) {
      predicate = cb.equal(root.get(VasOrder_.productCode), sc.getProductCode());
      predicates.add(predicate);
    }

//    if (!isAdmin) {
//      //非管理员，指定的产品代码只能查看自己创建的
//      predicate = cb.equal(root.get(VasOrder_.operator), username);
//      predicate = cb.and(predicate, cb.equal(root.get(VasOrder_.status), VasOrder.STATUS_DONE));
//
//      predicate = cb.or(predicate, cb.notEqual(root.get(VasOrder_.status), VasOrder.STATUS_DONE));
//
//      predicates.add(predicate);
//    }

    if (sc.getOrderType() == 1) {
      predicate = cb.equal(root.get(VasOrder_.orderType), 1);
      predicates.add(predicate);
    } else {
      predicate = cb.isNull(root.get(VasOrder_.orderType));
      predicate = cb.or(predicate, cb.equal(root.get(VasOrder_.orderType), 0));
      predicates.add(predicate);
    }

    if (sc.getOp1().length() > 0) {
      //查找指定用户名的订单
      predicate = cb.equal(root.get(VasOrder_.operator), sc.getOp1());
      predicates.add(predicate);
    }
    if (sc.getDepartmentId() != null) {
      //只查找本部门的
      List<String> usernames = doGetCustomerDepartmentOperator(ownerId, customerId, sc.getDepartmentId());

      Path<String> path = root.get(VasOrder_.operator);
      CriteriaBuilder.In<String> in = cb.in(path);
      for(String username: usernames) {
        in.value(username);
      }

      predicates.add(in);
    }
    return predicates;
  }

  @Override
  public List<VasOrder> searchByFlightOrderId(int ownerId, int flightOrderId) {
    return em.createQuery("select o from VasOrder o " +
        "where o.enterpriseId = :enterpriseId and o.flightOrderId = :flightOrderId and o.status <> :status order by o.productName", VasOrder.class)
        .setParameter("enterpriseId", ownerId)
        .setParameter("flightOrderId", flightOrderId)
        .setParameter("status", ORDER_STATUS_CANCELED)
        .getResultList();
  }

  @Override
  public VasOrder getOrderById(int id) {
    VasOrder order = em.find(VasOrder.class, id);
//    if (order == null) {
//      return null;
//    }
//
//    order.getPassengers().size();

    return order;
  }

  @Override
  public int createVasOrder(VasOrder o) {
    int retCode;
    em.persist(o);

    OperationLog log = OperationLogFactory.createVasOrderOperationLog();
    log.setEnterpriseId(o.getEnterpriseId());
    log.setOrderId(o.getId());
    log.setOperator(o.getOperator());
    log.setContent("创建订单");

    em.persist(log);

    retCode = o.getId();

    return retCode;
  }

  @Override
  public int updateVasOrderPaid(final int userId, final int orderId) {
    User user = em.find(User.class, userId);
    VasOrder vasOrder = em.find(VasOrder.class, orderId);
    final int customerId = vasOrder.getCustomer().getId();

    int retCode = em.createQuery("update VasOrder o " +
            "set o.payStatus = :payStatus, " +
            "o.lastUpdate = :lastUpdate " +
            "where o.id = :id and (o.payStatus is null or o.payStatus <> :payStatus)")
            .setParameter("id", orderId)
            .setParameter("payStatus", 1)
            .setParameter("lastUpdate", DateUtil.getCurDateTime())
            .executeUpdate();
    if (retCode != 1) {
      throw new RuntimeException("update vaas-order's pay status failed.");
    }

    OperationLog log = OperationLog.createLog(vasOrder.getEnterpriseId(), OPERATING_OBJECT_VAS_ORDER);
    log.setCustomerId(customerId);
    log.setOperator(user.getUsername());
    log.setOrderId(orderId);
    log.setContent("订单支付完成");
    em.persist(log);

    return retCode;
  }
}
